/*
Copyright (C) Ariff Ehsan, Abdul Hadi Fikri

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

/*  Author : Ariff Ehsan
 *  Date   : June 18, 2009
 */


#ifndef __TIMER_H__
#define __TIMER_H__

#ifdef CLOCK_PULSE

#ifndef CLOCK_PULSE_PORT
#error clock pulse port is not defined
#endif

#ifndef CLOCK_PULSE_DDR
#error clock pulse ddr is not defined
#endif

#ifndef CLOCK_PULSE_PIN
#error clock pulse pin is not defined
#endif

#warning the clock pulse output is enabled

#endif // CLOCK_PULSE


/** 
 *  structure of timer data type
 */
typedef struct timer_t {
  uint8_t started : 1;
  uint8_t periodic : 1;

  uint16_t period;
  uint32_t expired;

  void (*run)(void);

  struct timer_t *prev;
  struct timer_t *next;
} timer_t;


/**
 *  timer initialization
 *  - to be called in system initialization
 */
extern void TIMER_init(void);

/**
 *  timer run
 *  - start running the timer
 */
extern void TIMER_run(void);

/**
 *  timer register
 *  - register the timer object with its event function
 */
extern void TIMER_reg(timer_t *t, void (*run)(void));

/**
 *  timer start single delay
 *  - execute a single delay for the given timer object
 *  - time is in milliseconds
 */
extern void TIMER_start(timer_t *t, uint16_t time);

/**
 *  timer start periodic delay
 *  - execute a periodic delay for the given timer object
 *  - time is in milliseconds
 */
extern void TIMER_startPeriodic(timer_t *t, uint16_t time);

/**
 *  timer stop
 *  - stop the given timer execution
 */
extern void TIMER_stop(timer_t *t);

/*
 *  get current timer clock
 *  - the return value is in milliseconds
 */
extern uint32_t TIMER_getNow(void);

/**
 *  get the given timer status
 *  - return true if the timer is running
 *  - else return false
 */
BOOL TIMER_isRunning(timer_t*);


#endif // __TIMER_H__
